/**
 * 
 */
package ua.lviv.franko.mlsFunctions.oneDimension.weightFunctions;

import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import ua.lviv.franko.visualisation.NewOkCancelDialog;

/**
 * @author marko
 * 
 */
public class Exponential extends IWeightFunction {

	private double	c;
	private int		k;

	/**
	 * By default c = 0.25, k = 1.
	 */
	public Exponential() {
		c = 0.25;
		k = 1;
	}

	/**
	 * 
	 * @param c
	 *            constant;
	 * @param k
	 *            half of power degree; Creates an exponential weighting
	 *            function
	 */

	public Exponential(double c, int k) {
		this.c = c;
		this.k = k;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see mlsFunctions.oneDimension.IWeightFunction#calculate(double, double,
	 * double)
	 */
	@Override
	public double calculate(double x, double xi, double rho) {
		double xxx = Math.abs((x - xi) / rho);
		if (Math.abs(xxx) > 1.0) {
			return 0;
		} else {
			return Math.exp(-Math.pow(xxx / c, 2 * k));
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see mlsFunctions.oneDimension.IWeightFunction#calculateDerivaty(double,
	 * double, double)
	 */
	@Override
	public double calculateDerivaty(double x, double xi, double rho) {
		double xxx = Math.abs((x - xi) / rho);
		if (Math.abs(xxx) > 1.0) {
			return 0;
		} else {
			return Math.exp(-Math.pow(xxx / c, 2 * k)) * (-Math.pow(xxx / c, 2 * k - 1) / c * (2 * k)) / rho * Math.signum((x - xi) / rho);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * mlsFunctions.oneDimension.IWeightFunction#calculateSecondDerivaty(double,
	 * double, double)
	 */
	@Override
	public double calculateSecondDerivaty(double x, double xi, double rho) {
		double xxx = Math.abs((x - xi) / rho);
		if (Math.abs(xxx) > 1.0) {
			return 0;
		} else {
			return (Math.exp(-Math.pow(xxx / c, 2 * k)) * (-Math.pow(xxx / c, 2 * k - 2) / c / c * (2 * k) * (2 * k - 1)) + Math.exp(-Math.pow(xxx / c, 2 * k))
					* Math.pow((-Math.pow(xxx / c, 2 * k - 1) / c * (2 * k)), 2))
					/ rho / rho;
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		double a = -1.5, b = 1.5, h = 0.01;
		double x = a;

		IWeightFunction f = new Exponential();

		XYSeries series1 = new XYSeries("Function", true, true);
		XYSeries series2 = new XYSeries("Function derivaty", true, true);
		XYSeries series3 = new XYSeries("Function second derivaty", true, true);

		double xi = 0.0;
		double rho = 0.5;

		while (x < b + h) {
			series1.add(x, f.calculate(x, xi, rho));
			series2.add(x, f.calculateDerivaty(x, xi, rho));
			// series2.add(x,Derivaty.calculate2(x, xi, rho, f));
			series3.add(x, f.calculateSecondDerivaty(x, xi, rho));
			x += h;
		}

		XYSeriesCollection col = new XYSeriesCollection(series1);
		col.addSeries(series2);
		col.addSeries(series3);

		NewOkCancelDialog dialog = new NewOkCancelDialog(null, false, col);
		dialog.setLocationRelativeTo(null);
		dialog.setVisible(true);
	}

}
